﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.Core;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Security.Authentication.Identity.Provider;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using MyHelloWinDevice;
using MyHelloWinJson;
using Windows.Devices.Bluetooth.Advertisement;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace MyHelloWin
{
    public class DerviceContextDisplay : INotifyPropertyChanged
    {
        public DerviceContextDisplay(DeviceContext Deviceinfo)
        {
            DeviceInformation = Deviceinfo;
        }

        public DeviceContext DeviceInformation { get; private set; }

        public string DeviceID => DeviceInformation.DeviceID;
        public string DeviceName => DeviceInformation.DeviceName;
        public DeviceType Type => DeviceInformation.Type;
        public Boolean IsConnetced => DeviceInformation.IsConnected;

        public string GUID;

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }

    public sealed partial class MainPage : Page
    {
        string m_TaskName_Unlock = "MyHelloWinTask_Unlock";
        string m_TaskEntryPoint = "Tasks.MyHelloWinTask";
        WinHelloInterface WinHello = new WinHelloInterface();
        CDeviceManger DeviceManger = new CDeviceManger();
        ObservableCollection<DerviceContextDisplay> UnRegisterDisplayDeviceList = new ObservableCollection<DerviceContextDisplay>();
        ObservableCollection<DerviceContextDisplay> RegisterDisplayDeviceList = new ObservableCollection<DerviceContextDisplay>();
        ObservableCollection<DerviceContextDisplay> AllDisplayDeviceList = new ObservableCollection<DerviceContextDisplay>();
        IReadOnlyList<SecondaryAuthenticationFactorInfo> RegisterDevicesList = null;
        
        public MainPage()
        {
            this.InitializeComponent();

            UpdateRegisterDerviceAsync();

            DeviceManger.Added += DeviceManger_Added;
            DeviceManger.Removed += DeviceManger_Removed;
            DeviceManger.Completed += DeviceManger_Completed;
            DeviceManger.Updated += DeviceManger_Updated;
            DeviceManger.Stopped += DeviceManger_Stopped;

            DeviceManger.StartMonitor();
        }

        private async void UpdateRegisterDerviceAsync()
        {
            RegisterDevicesList = await WinHello.EnumDevice();
        }

        private void DeviceManger_Stopped(CDeviceManger sender, object args)
        {
            //throw new NotImplementedException();
        }

        private void DeviceManger_Updated(CDeviceManger sender, DeviceContext args)
        {
            //throw new NotImplementedException();
        }

        private void DeviceManger_Completed(CDeviceManger sender, object args)
        {
            //throw new NotImplementedException();
        }

        private void DeviceManger_Removed(CDeviceManger sender, DeviceContext args)
        {
            //throw new NotImplementedException();
        }

        private async void DeviceManger_Added(CDeviceManger sender, DeviceContext args)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                AllDisplayDeviceList.Add(new DerviceContextDisplay(args));
                string GUID = "";
                // 判断设备是否已经被注册过了
                if (!IsDeviceRegister(args.DeviceID, args.Type, out GUID))
                {
                    args.IsRegistered = false;
                    UnRegisterDisplayDeviceList.Add(new DerviceContextDisplay(args));
                }
                else
                {
                    args.IsRegistered = true;
                    DerviceContextDisplay TMP = new DerviceContextDisplay(args);
                    TMP.GUID = GUID;
                    RegisterDisplayDeviceList.Add(TMP);
                }
            });
        }
        
        private bool IsDeviceRegister(string DeviceID, DeviceType type, out string GUID)
        {
            if (RegisterDevicesList != null)
            {
                for (int index = 0; index < RegisterDevicesList.Count; ++index)
                {
                    SecondaryAuthenticationFactorInfo deviceInfo = RegisterDevicesList.ElementAt(index);

                    byte[] combinedDataArray;
                    CryptographicBuffer.CopyToByteArray(deviceInfo.DeviceConfigurationData, out combinedDataArray);
                    string JS = System.Text.Encoding.UTF8.GetString(combinedDataArray);
                    JsonData Dat = CMyHelloWinJson.ParesToData(JS);
                    if (Dat != null)
                    {
                        if (String.Equals(DeviceID, Dat.DeviceID))
                        {
                            GUID = deviceInfo.DeviceId;
                            return true;
                        }
                    }
                }
            }

            GUID = null;
            return false;
        }

        private void UpdateView()
        {
            UpdateRegisterDerviceAsync();
            UnRegisterDisplayDeviceList.Clear();
            RegisterDisplayDeviceList.Clear();
            for (int index = 0; index < AllDisplayDeviceList.Count; ++index)
            {
                DerviceContextDisplay DeviceDisplay = AllDisplayDeviceList.ElementAt(index);
                // 判断设备是否已经被注册过了
                string GUID = "";
                if (!IsDeviceRegister(DeviceDisplay.DeviceID, DeviceDisplay.Type, out GUID))
                {
                    UnRegisterDisplayDeviceList.Add(DeviceDisplay);
                }
                else
                {
                    DeviceDisplay.GUID = GUID;
                    RegisterDisplayDeviceList.Add(DeviceDisplay);
                }
            }
        }

        private void Refresh_Click(object sender, RoutedEventArgs e)
        {
            UpdateView();
        }

        private void RemoveDevice_Click(object sender, RoutedEventArgs e)
        {
            string DeviceID = ((Button)sender).Name;
            for (int index = 0; index < RegisterDisplayDeviceList.Count; ++index)
            {
                DerviceContextDisplay DeviceDisplay = RegisterDisplayDeviceList.ElementAt(index);
                if (String.Equals(DeviceDisplay.DeviceID, DeviceID))
                {
                    // 删除设备
                    WinHello.UnRegisterDeviceAsync(DeviceDisplay.GUID);
                    UpdateView();
                }
            }
        }

        private async void AddDevice_Click(object sender, RoutedEventArgs e)
        {
            string DeviceID = ((Button)sender).Name;
            //foreach (DerviceContextDisplay bleDeviceDisplay in UnRegisterDisplayDeviceList)
            for (int index = 0; index < UnRegisterDisplayDeviceList.Count; ++index)
            {
                DerviceContextDisplay bleDeviceDisplay = UnRegisterDisplayDeviceList.ElementAt(index);
                if (String.Equals(bleDeviceDisplay.DeviceID , DeviceID))
                {
                    string modelnumber = String.Format("MyHelloWin-{0}", (int)bleDeviceDisplay.Type);

                    // 随机数转 string 会丢失信息的
                    byte[] deviceKeyArray = new byte[32];
                    byte[] authKeyArray = new byte[32];

                    IBuffer deviceKey = CryptographicBuffer.CreateFromByteArray(deviceKeyArray);
                    IBuffer authKey = CryptographicBuffer.CreateFromByteArray(authKeyArray);

                    JsonData Dat = new JsonData();
                    Dat.Sign = "MyHellowin";
                    Dat.DeviceKey = System.Text.Encoding.UTF8.GetString(deviceKeyArray);
                    Dat.AuthKey = System.Text.Encoding.UTF8.GetString(authKeyArray);
                    Dat.DeviceID = DeviceID;
                    Dat.CanUnLock = false;

                    string js = CMyHelloWinJson.ParesToJson(Dat);
                    byte[] signArry = System.Text.Encoding.UTF8.GetBytes(js);
                    IBuffer deviceConfigData = CryptographicBuffer.CreateFromByteArray(signArry);
                    String deviceGUId = System.Guid.NewGuid().ToString();
                    int state = await WinHello.RegisterDeviceAsync(deviceGUId, bleDeviceDisplay.DeviceName, modelnumber, deviceConfigData, deviceKey, authKey);

                    // 添加设备
                    UpdateView();
                }
            }
        }

        private void Start_Click(object sender, RoutedEventArgs e)
        {
            // 清除已经注册的任务
            foreach (var task in BackgroundTaskRegistration.AllTasks)
            {
                if (m_TaskName_Unlock == task.Value.Name)
                {
                    task.Value.Unregister(true);
                }
            }

            // 注册解锁后台任务
            {
                BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
                taskBuilder.Name = m_TaskName_Unlock;
                SecondaryAuthenticationFactorAuthenticationTrigger myTrigger = new SecondaryAuthenticationFactorAuthenticationTrigger();
                taskBuilder.TaskEntryPoint = m_TaskEntryPoint;
                taskBuilder.SetTrigger(myTrigger);
                BackgroundTaskRegistration taskReg = taskBuilder.Register();
            }

            // 启动后台任务
            DeviceManger.ClearMonitorWithTask("MyHelloWinTask");
            DeviceManger.RegistMonitorWithTask("MyHelloWinTask", m_TaskEntryPoint);
        }

        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            // 清除已经注册的任务
            DeviceManger.ClearMonitorWithTask("MyHelloWinTask");
        }
    }
}